package com.dily.study.demo.study;

import java.util.Scanner;

/**
 * 五子棋
 */
public class Gobang {

    private int step = 0;
    private int currentX = -1;
    private int currentY = -1;
    private int currentPlayer = 1;
    private boolean end = false;
    private int winner = 0;
    private final int size = 19;  // 棋盘大小
    private final int[][] gridData = new int[size][size];

    Scanner scanner;

    public Gobang() {
        for (int i = 0; i < size; i++) {
            int[] row = gridData[i];
            for (int j = 0; j < size; j++) {
                row[j] = 0;
            }
        }
        scanner = new Scanner(System.in);
    }

    /**
     * 在控制台绘制棋盘
     */
    public void draw() {
        // 打印行码
        for (int i = 1; i <= size; i++) {
            if (i < 10)
                System.out.print(" " + i + " ");
            else
                System.out.print(" " + i);
        }
        System.out.println();
        for (int i = 0; i < size; i++) {
            int[] row = gridData[i];
            for (int j = 0; j < size; j++) {
                String fill;
                if (row[j] == 1) {
                    fill = "\u25EF";
                } else if (row[j] == 2) {
                    fill = "\u25CF";
                } else {
                    fill = "\u253C";
                }
                fill += "\u2500";
                System.out.print("\u2500" + fill);
                if (j == row.length - 1) {
                    System.out.println("\u2500" + (i + 1));
                }
            }
        }
    }

    /**
     * 落子下棋
     *
     * @param x      棋盘坐标x
     * @param y      棋盘坐标y
     * @param player 用户1用户2
     * @return 这一步是否成功
     */
    private boolean go(int x, int y, int player) {
        if (x < 1 || x > size || y < 1 || y > size) {
            System.out.println("超出棋盘位置，请重新落子");
            return false;
        }
        if (gridData[y - 1][x - 1] != 0) {
            System.out.println("该位置已有棋子");
            return false;
        }
        gridData[y - 1][x - 1] = player;
        currentX = x - 1;
        currentY = y - 1;
        step++;
        return true;
    }

    public void userInput() {
        System.out.println("请玩家" + currentPlayer + "输入棋子位置，请输入两个数字，用,分隔，例如1,2棋子将放在第一列第二行");
        String input = scanner.nextLine();
        String[] strs = input.split(",");
        if (strs.length != 2) {
            System.out.println("请输入正确的格式");
            userInput();
            return;
        }
        try {
            int x = Integer.parseInt(strs[0].trim());
            int y = Integer.parseInt(strs[1].trim());
            boolean boo = go(x, y, currentPlayer);
            if (!boo) {
                userInput();
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
            System.out.println("请输入正确的数字");
            userInput();
        }
    }

    private void judge() {
        // 1.检查行
        int lineAmount = 1;
        // 先左边
        int checkX = currentX - 1;
        while (checkX >= 0) {
            int data = gridData[currentY][checkX];
            if (data == currentPlayer) {
                lineAmount++;
                checkX--;
            } else {
                break;
            }
        }
        // 再右边
        checkX = currentX + 1;
        while (checkX < size) {
            int data = gridData[currentY][checkX];
            if (data == currentPlayer) {
                lineAmount++;
                checkX++;
            } else {
                break;
            }
        }
        // 连成几个算赢
        int winNum = 5;
        if (lineAmount == winNum) {
            winner = currentPlayer;
            end = true;
            return;
        }

        // 2.检查列
        lineAmount = 1;
        // 先上面
        int checkY = currentY - 1;
        while (checkY >= 0) {
            int data = gridData[checkY][currentX];
            if (data == currentPlayer) {
                lineAmount++;
                checkY--;
            } else {
                break;
            }
        }
        // 再下面
        checkY = currentY + 1;
        while (checkY < size) {
            int data = gridData[checkY][currentX];
            if (data == currentPlayer) {
                lineAmount++;
                checkY++;
            } else {
                break;
            }
        }
        if (lineAmount == size) {
            winner = currentPlayer;
            end = true;
            return;
        }

        // 3.检查西北东南斜线
        lineAmount = 1;
        // 先西北
        checkX = currentX - 1;
        checkY = currentY - 1;
        while (checkX >= 0 && checkY >= 0) {
            int data = gridData[checkY][checkX];
            if (data == currentPlayer) {
                lineAmount++;
                checkX--;
                checkY--;
            } else {
                break;
            }
        }
        // 再东南
        checkX = currentX + 1;
        checkY = currentY + 1;
        while (checkX < size && checkY < size) {
            int data = gridData[checkY][checkX];
            if (data == currentPlayer) {
                lineAmount++;
                checkX++;
                checkY++;
            } else {
                break;
            }
        }
        if (lineAmount == size) {
            winner = currentPlayer;
            end = true;
            return;
        }

        // 4.检查西南东北斜线
        lineAmount = 1;
        // 先西南
        checkX = currentY - 1;
        checkY = currentY + 1;
        while (checkX >= 0 && checkY < size) {
            int data = gridData[checkY][checkX];
            if (data == currentPlayer) {
                lineAmount++;
                checkX--;
                checkY++;
            } else {
                break;
            }
        }
        // 再东北
        checkX = currentY + 1;
        checkY = currentY - 1;
        while (checkX < size && checkY >= 0) {
            int data = gridData[checkY][checkX];
            if (data == currentPlayer) {
                lineAmount++;
                checkX++;
                checkY--;
            } else {
                break;
            }
        }
        if (lineAmount == size) {
            winner = currentPlayer;
            end = true;
            return;
        }

        if (step == size * size) {
            end = true;
        } else {
            if (currentPlayer == 1) {
                currentPlayer = 2;
            } else {
                currentPlayer = 1;
            }
        }
    }

    public void printWinner() {
        if (winner == 1) {
            System.out.println("恭喜玩家1在本局获胜！");
        } else if (winner == 2) {
            System.out.println("恭喜玩家2在本局获胜！");
        } else {
            System.out.println("本局结束，平局。");
        }
    }

    public static void main(String[] args) {
        Gobang gobang = new Gobang();
        while (!gobang.end) {
            gobang.userInput();
            gobang.draw();
            gobang.judge();
        }
        gobang.printWinner();
        gobang.scanner.close();
    }

}
